<template>
  <div class="draw">
    <div class="drawTop" ref="drawTop" v-if="lineStep == lineNum">
      <div>
        <el-button type @click="resetAll">清空</el-button>
        <el-button type @click="repeal">撤销</el-button>
        <el-button type @click="canvasRedo">恢复</el-button>
        <el-button type @click="downLoad">下载</el-button>
      </div>
      <div style="width:22%">
        选择绘制类型:
        <el-radio-group v-model="type" size="medium">
          <el-radio-button
            v-for="(item,index) in typeOption"
            :key="index"
            :label="item.value"
            @click.native="radioClick(item.value)"
          >{{item.label}}
          </el-radio-button>
        </el-radio-group>
      </div>
      <div style="width:15%">
        边框粗细:
        <el-slider v-model="lineWidth" :min="0" :max="10" :step="1" style="width:70%"></el-slider>
      </div>
      <div>
        线条颜色:
        <el-color-picker v-model="strokeStyle"></el-color-picker>
      </div>
      <div>
        文字颜色:
        <el-color-picker v-model="fontColor"></el-color-picker>
      </div>
      <div style="width:15%">
        文字大小:
        <el-slider v-model="fontSize" :min="14" :max="36" :step="2" style="width:70%"></el-slider>
      </div>
    </div>
    <div style="height: 100%;width: 100%;position:relative;">
      <div class="content"></div>
      <input v-show="isShow" type="text" @blur="txtBlue" ref="txt" id="txt"
             style="z-index: 9999;position: absolute;border: 0;background:none;outline: none;"/>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Label',
  props: {
    //imgPath: '../assets/logo.jpg'
    imgPath: 'https://img.baidu.com/img/logo-zhidao.gif'
    //undefined

  },
  data () {
    return {
      isShow: false,
      canvas: '',
      ctx: '',
      ctxX: 0,
      ctxY: 0,
      lineWidth: 1,
      type: 'L',
      typeOption: [
        {label: '线', value: 'L'},
        {label: '矩形', value: 'R'},
        {label: '箭头', value: 'A'},
        {label: '文字', value: 'T'},
        {label: '多边形', value: 'D'}
      ],
      canvasHistory: [],
      step: 0,
      loading: false,
      fillStyle: '#CB0707',
      strokeStyle: '#CB0707',
      lineNum: 2,
      linePeak: [],
      lineStep: 2,
      ellipseR: 0.5,
      dialogVisible: false,
      isUnfold: true,
      fontSize: 24,
      fontColor: '#CB0707',
      fontFamily: '微软雅黑',
      img: new Image()
    }
  },
  mounted () {
    let _this = this
    let image = new Image()
    image.setAttribute('crossOrigin', 'anonymous')
    this.imgPath='https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1823408532,1768644765&fm=26&gp=0.jpg'
    image.src = this.imgPath
    console.log(this.imgPath)
    console.log(image.src)
    image.onload = function () { // 图片加载完，再draw 和 toDataURL
      if (image.complete) {
        _this.img = image
        let content = document.getElementsByClassName('content')[0]
        _this.canvas = document.createElement('canvas')
        _this.canvas.height = _this.img.height
        _this.canvas.width = _this.img.width
        _this.ctx = _this.canvas.getContext('2d')
        _this.ctx.globalAlpha = 1
        _this.ctx.drawImage(_this.img, 0, 0)
        _this.canvasHistory.push(_this.canvas.toDataURL())
        _this.ctx.globalCompositeOperation = _this.type
        content.appendChild(_this.canvas)
        _this.bindEventLisner()
      }
    }
  },
  methods: {
    radioClick (item) {
      if (item != 'T') {
        this.txtBlue()
        this.resetTxt()
      }
    },
    // 下载画布
    downLoad () {
      let _this = this
      let url = _this.canvas.toDataURL('image/png')
      let fileName = 'canvas.png'
      if ('download' in document.createElement('a')) {
        // 非IE下载
        const elink = document.createElement('a')
        elink.download = fileName
        elink.style.display = 'none'
        elink.href = url
        document.body.appendChild(elink)
        elink.click()
        document.body.removeChild(elink)
      } else {
        // IE10+下载
        navigator.msSaveBlob(url, fileName)
      }
    },
    // 清空画布及历史记录
    resetAll () {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
      this.canvasHistory = []
      this.ctx.drawImage(this.img, 0, 0)
      this.canvasHistory.push(this.canvas.toDataURL())
      this.step = 0
      this.resetTxt()
    },
    // 清空当前画布
    reset () {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
      this.ctx.drawImage(this.img, 0, 0)
      this.resetTxt()
    },
    // 撤销方法
    repeal () {
      let _this = this
      if (this.isShow) {
        _this.resetTxt()
        _this._repeal()
      } else {
        _this._repeal()
      }
    },
    _repeal () {
      if (this.step >= 1) {
        this.step = this.step - 1
        let canvasPic = new Image()
        canvasPic.src = this.canvasHistory[this.step]
        canvasPic.addEventListener('load', () => {
          this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
          this.ctx.drawImage(canvasPic, 0, 0)
          this.loading = true
        })
      } else {
        this.$message.warning('不能再继续撤销了')
      }
    },
    // 恢复方法
    canvasRedo () {
      if (this.step < this.canvasHistory.length - 1) {
        if (this.step == 0) {
          this.step = 1
        } else {
          this.step++
        }
        let canvasPic = new Image()
        canvasPic.src = this.canvasHistory[this.step]
        canvasPic.addEventListener('load', () => {
          this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
          this.ctx.drawImage(canvasPic, 0, 0)
        })
      } else {
        this.$message.warning('已经是最新的记录了')
      }
    },
    // 绘制历史数组中的最后一个
    rebroadcast () {
      let canvasPic = new Image()
      canvasPic.src = this.canvasHistory[this.step]
      canvasPic.addEventListener('load', () => {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
        this.ctx.drawImage(canvasPic, 0, 0)
        this.loading = true
      })
    },
    // 绑定事件,判断分支
    bindEventLisner () {
      let _this = this
      let r1, r2 // 绘制圆形，矩形需要
      this.canvas.onmousedown = function (e) {
        console.log('onmousedown')
        if (_this.type == 'L') {
          _this.createL(e, 'begin')
        } else if (_this.type == 'R') {
          r1 = e.layerX
          r2 = e.layerY
          _this.createR(e, 'begin', r1, r2)
        } else if (_this.type == 'A') {
          _this.drawArrow(e, 'begin')
        } else if (_this.type == 'T') {
          _this.createT(e, 'begin')
        } else {

        }
      }
      this.canvas.onmouseup = function (e) {
        console.log('onmouseup')
        if (_this.type == 'L') {
          _this.createL(e, 'end')
        } else if (_this.type == 'R') {
          _this.createR(e, 'end', r1, r2)
          r1 = null
          r2 = null
        } else if (_this.type == 'A') {
          _this.drawArrow(e, 'end')
        } else if (_this.type == 'T') {
          _this.createT(e, 'end')
        }
      }
    },
    // 绘制线条
    createL (e, status) {
      let _this = this
      if (status == 'begin') {
        _this.ctx.beginPath()
        _this.ctx.moveTo(e.layerX, e.layerY)
        _this.canvas.onmousemove = function (e) {
          console.log('onmousemove')
          _this.ctx.lineTo(e.layerX, e.layerY)
          _this.ctx.strokeStyle = _this.strokeStyle
          _this.ctx.lineWidth = _this.lineWidth
          _this.ctx.stroke()
        }
      } else if (status == 'end') {
        _this.ctx.closePath()
        _this.step = _this.step + 1
        if (_this.step < _this.canvasHistory.length - 1) {
          _this.canvasHistory.length = _this.step // 截断数组
        }
        _this.canvasHistory.push(_this.canvas.toDataURL())
        _this.canvas.onmousemove = null
      }
    },
    // 绘制矩形
    createR (e, status, r1, r2) {
      let _this = this
      let r
      if (status == 'begin') {
        console.log('onmousemove')
        _this.canvas.onmousemove = function (e) {
          _this.reset()
          let rx = e.layerX - r1
          let ry = e.layerY - r2

          // 保留之前绘画的图形
          if (_this.step !== 0) {
            let canvasPic = new Image()
            canvasPic.src = _this.canvasHistory[_this.step]
            _this.ctx.drawImage(canvasPic, 0, 0)
          }

          _this.ctx.beginPath()
          _this.ctx.strokeRect(r1, r2, rx, ry)
          _this.ctx.strokeStyle = _this.strokeStyle
          _this.ctx.lineWidth = _this.lineWidth
          _this.ctx.closePath()
          _this.ctx.stroke()
        }
      } else if (status == 'end') {
        _this.rebroadcast()
        let interval = setInterval(() => {
          if (_this.loading) {
            clearInterval(interval)
            _this.loading = false
          } else {
            return
          }
          let rx = e.layerX - r1
          let ry = e.layerY - r2
          _this.ctx.beginPath()
          _this.ctx.rect(r1, r2, rx, ry)
          _this.ctx.strokeStyle = _this.strokeStyle
          _this.ctx.lineWidth = _this.lineWidth
          _this.ctx.closePath()
          _this.ctx.stroke()
          _this.step = _this.step + 1
          if (_this.step < _this.canvasHistory.length - 1) {
            _this.canvasHistory.length = _this.step // 截断数组
          }
          _this.canvasHistory.push(_this.canvas.toDataURL())
          _this.canvas.onmousemove = null
        }, 1)
      }
    },

    // 绘制箭头
    drawArrow (e, status) {
      let _this = this
      if (status == 'begin') {
        // 获取起始位置
        _this.arrowFromX = e.layerX
        _this.arrowFromY = e.layerY
        _this.ctx.beginPath()
        _this.ctx.moveTo(e.layerX, e.layerY)
      } else if (status == 'end') {
        // 计算箭头及画线
        let toX = e.layerX
        let toY = e.layerY
        let theta = 30
        let headlen = 10
        let _this = this
        let fromX = this.arrowFromX
        let fromY = this.arrowFromY
        // 计算各角度和对应的P2,P3坐标
        let angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI,
          angle1 = (angle + theta) * Math.PI / 180,
          angle2 = (angle - theta) * Math.PI / 180,
          topX = headlen * Math.cos(angle1),
          topY = headlen * Math.sin(angle1),
          botX = headlen * Math.cos(angle2),
          botY = headlen * Math.sin(angle2)
        let arrowX = fromX - topX,
          arrowY = fromY - topY
        _this.ctx.moveTo(arrowX, arrowY)
        _this.ctx.moveTo(fromX, fromY)
        _this.ctx.lineTo(toX, toY)
        arrowX = toX + topX
        arrowY = toY + topY
        _this.ctx.moveTo(arrowX, arrowY)
        _this.ctx.lineTo(toX, toY)
        arrowX = toX + botX
        arrowY = toY + botY
        _this.ctx.lineTo(arrowX, arrowY)
        _this.ctx.strokeStyle = _this.strokeStyle
        _this.ctx.lineWidth = _this.lineWidth
        _this.ctx.stroke()

        _this.ctx.closePath()
        _this.step = _this.step + 1
        if (_this.step < _this.canvasHistory.length - 1) {
          _this.canvasHistory.length = _this.step // 截断数组
        }
        _this.canvasHistory.push(_this.canvas.toDataURL())
        _this.canvas.onmousemove = null
      }
    },

    // 文字输入
    createT (e, status) {
      let _this = this
      if (status == 'begin') {

      } else if (status == 'end') {
        let offset = 0
        if (_this.fontSize >= 28) {
          offset = (_this.fontSize / 2) - 3
        } else {
          offset = (_this.fontSize / 2) - 2
        }

        _this.ctxX = e.layerX + 2
        _this.ctxY = e.layerY + offset

        let index = this.getPointOnCanvas(e)
        _this.$refs.txt.style.left = index.x + 'px'
        _this.$refs.txt.style.top = index.y - (_this.fontSize / 2) + 'px'
        _this.$refs.txt.value = ''
        _this.$refs.txt.style.height = _this.fontSize + 'px'
        _this.$refs.txt.style.width = _this.canvas.width - e.layerX - 1 + 'px',
        _this.$refs.txt.style.fontSize = _this.fontSize + 'px'
        _this.$refs.txt.style.fontFamily = _this.fontFamily
        _this.$refs.txt.style.color = _this.fontColor
        _this.$refs.txt.style.maxlength = Math.floor((_this.canvas.width - e.layerX) / _this.fontSize)
        _this.isShow = true
        setTimeout(() => {
          _this.$refs.txt.focus()
        })
      }
    },
    // 文字输入框失去光标时在画布上生成文字
    txtBlue () {
      let _this = this
      let txt = _this.$refs.txt.value
      if (txt) {
        _this.ctx.font = _this.$refs.txt.style.fontSize + ' ' + _this.$refs.txt.style.fontFamily
        _this.ctx.fillStyle = _this.$refs.txt.style.color
        _this.ctx.fillText(txt, _this.ctxX, _this.ctxY)
        _this.step = _this.step + 1
        if (_this.step < _this.canvasHistory.length - 1) {
          _this.canvasHistory.length = _this.step // 截断数组
        }
        _this.canvasHistory.push(_this.canvas.toDataURL())
        _this.canvas.onmousemove = null
      }
    },
    // 计算文字框定位位置
    getPointOnCanvas (e) {
      let cs = this.canvas
      let content = document.getElementsByClassName('content')[0]
      return {
        x: e.layerX + (content.clientWidth - cs.width) / 2,
        y: e.layerY
      }
    },
    // 清空文字
    resetTxt () {
      let _this = this
      _this.$refs.txt.value = ''
      _this.isShow = false
    }
  }
}
</script>

<style scope>
* {
  box-sizing: border-box;
}

body,
html,
#app {
  overflow: hidden;
}

.draw {
  height: 100%;
  min-width: 420px;
  display: flex;
  flex-direction: column;
}

.content {
  flex-grow: 1;
  height: 100%;
  width: 100%;
}

.drawTop {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding: 5px;
  height: 52px;
}

.drawTop > div {
  display: flex;
  align-items: center;
  padding: 5px 5px;
}

div.drawTopContrllor {
  display: none;
}

@media screen and (max-width: 1200px) {
  .drawTop {
    position: absolute;
    background-color: white;
    width: 100%;
    flex-direction: column;
    align-items: flex-start;
    height: 30px;
    overflow: hidden;
  }

  .drawTopContrllor {
    display: flex !important;
    height: 30px;
    width: 100%;
    justify-content: center;
    align-items: center;
    padding: 0 !important;
  }
}
</style>
